package xmla

import (
	"io"
	"encoding/xml"
	"fmt"
)

type ErrDiscoverResponse struct{
	ErrorCode   string
	Description  string
	Source string
	HelpFile string
}
func IsErrDiscoverResponse(err error) bool {
	_, ok := err.(ErrDiscoverResponse)
	return ok
}

func (err ErrDiscoverResponse) Error() string {
	return fmt.Sprintf("错误代码: %s； \n错误描述: %s；\n错误源：%s", 
	                    err.ErrorCode, err.Description,err.Source)
}

type ErrExecuteResponse struct{
	ErrorCode   string
	Description  string
	Source string
	HelpFile string
}

func NewErrExecuteResponse(d *xml.Decoder) ErrExecuteResponse{
	var isFinish bool= false
	errExec:=ErrExecuteResponse{}
	lab:
	for !isFinish {
		t, err := d.Token()
		if err == io.EOF {
			break
		}
		if err != nil {
			return errExec
		}
		switch t := t.(type) {
		case xml.EndElement:
			if t.Name.Local=="Error"{
				isFinish=true;
			}
		case xml.StartElement:
			if t.Name.Local=="Error"{
				for _, attr := range t.Attr {
					if attr.Name.Local=="ErrorCode" {
						errExec.ErrorCode=attr.Value
					}else if attr.Name.Local=="Description" {
						errExec.Description=attr.Value
					}else if attr.Name.Local=="Source" {
						errExec.Source=attr.Value
					}else if attr.Name.Local=="HelpFile" {
						errExec.HelpFile=attr.Value
					}
				}
			}
		case xml.CharData:
		    goto lab
		case xml.Comment:
			goto lab
		case xml.ProcInst:
			goto lab
		}
	}
	return errExec
}


func IsErrExecuteResponse(err error) bool {
	_, ok := err.(ErrExecuteResponse)
	return ok
}

func (err ErrExecuteResponse) Error() string {
	return fmt.Sprintf("错误代码: %s； \n错误描述: %s；\n错误源：%s", 
	                    err.ErrorCode, err.Description,err.Source)
}

type ErrSoapFault struct{
	ErrorCode   string
	Description  string
	Source string
	HelpFile string
}

func NewErrSoapFault(d *xml.Decoder) ErrSoapFault{
	var isFinish bool= false
	errSoap:=ErrSoapFault{}
	lab:
	for !isFinish {
		t, err := d.Token()
		if err == io.EOF {
			break
		}
		if err != nil {
			return errSoap
		}
		switch t := t.(type) {
		case xml.EndElement:
			if t.Name.Local=="Error"{
				isFinish=true;
			}
		case xml.StartElement:
			if t.Name.Local=="Error"{
				for _, attr := range t.Attr {
					if attr.Name.Local=="ErrorCode" {
						errSoap.ErrorCode=attr.Value
					}else if attr.Name.Local=="Description" {
						errSoap.Description=attr.Value
					}else if attr.Name.Local=="Source" {
						errSoap.Source=attr.Value
					}else if attr.Name.Local=="HelpFile" {
						errSoap.HelpFile=attr.Value
					}
				}
			}
		case xml.CharData:
		    goto lab
		case xml.Comment:
			goto lab
		case xml.ProcInst:
			goto lab
		}
	}
	return errSoap
}

func IsErrSoapFault(err error) bool {
	_, ok := err.(ErrSoapFault)
	return ok
}

func (err ErrSoapFault) Error() string {
	return fmt.Sprintf("错误代码: %s； \n错误描述: %s；\n错误源：%s", 
	                    err.ErrorCode, err.Description,err.Source)
}
